#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from common.cleaner import clear
from hcs.gaussdb.common.gaussdb_restful import request_get, request_post
from hcs.gaussdb.logger import log
from hcs.sdk.ability.hcs_manager_ability import HcsManagerAbility


class HcsManager:
    @staticmethod
    def get_token(json_param_object, pid):
        log.info("start to get token")
        project_name = HcsManager.get_params_by_key(json_param_object, "projectName")
        project_domain = HcsManager.get_params_by_key(json_param_object, "iamAccountName")
        # 获取token的url
        ctrl_addr = HcsManager.get_params_by_key(json_param_object, "pmAddress")

        ret, body, header = HcsManagerAbility.get_tokens_json(pid, project_domain, project_name, ctrl_addr)

        if not ret:
            log.error("Failed get Token!")
            return {}
        token = header.get("X-Subject-Token", None)
        if not token:
            log.error("Failed get Token!")
            return {}
        return token

    @staticmethod
    def get_job_progress(json_param_object, pid, backup_job_id):
        token = HcsManager.get_token(json_param_object, pid)
        project_id = HcsManager.get_params_by_key(json_param_object, "projectId")
        ctrl_domain = HcsManager.get_params_by_key(json_param_object, "businessAddr")
        get_backup_status_url = f'{ctrl_domain}/gaussdb/v3/{project_id}/jobs?id={backup_job_id}'
        backup_header = {'X-Auth-Token': token, 'X-Language': 'en-us'}
        backup_body = {}
        log.info(f"get_job_progress get_log_backup_status_url{get_backup_status_url}")
        ret, ret_body, ret_header = request_get(get_backup_status_url, backup_body, backup_header)
        clear(token)
        if not ret:
            log.error("Failed get progress!")
            return {}
        if ret_body.get("error_code"):
            log.error(f'Exec GET error with return: {ret_body.get("error_msg")}')
            return {}
        log.info(f"get_job_progress: {ret_body}")
        return ret_body

    @staticmethod
    def get_log_backup_job_progress(json_param_object, pid, instance_id, backup_id):
        backup_body = {}
        token = HcsManager.get_token(json_param_object, pid)
        project_id = HcsManager.get_params_by_key(json_param_object, "projectId")

        # 备份的url
        ctrl_domain = HcsManager.get_params_by_key(json_param_object, "businessAddr")
        get_log_backup_status_url = f'{ctrl_domain}/gaussdb/v3.1/{project_id}/backups?' \
                                    f'instance_id={instance_id}&backup_type=Log_Xbsa&backup_id={backup_id}'
        backup_header = {'X-Auth-Token': token, 'X-Language': 'en-us'}
        log.info(f"get_log_backup_job_progress get_log_backup_status_url{get_log_backup_status_url}")
        ret, ret_body, ret_header = request_get(get_log_backup_status_url, backup_body, backup_header)
        clear(token)
        if not ret:
            log.error("Failed get progress!")
            return {}
        if ret_body.get("error_code"):
            log.error(f'Exec GET error with return: {ret_body.get("error_msg")}')
            return {}
        log.info(f"get_log_back_progress: {ret_body}")
        return ret_body

    @staticmethod
    def get_backup_jobs_info(json_param_object, pid, instance_id):
        backup_body = {}
        token = HcsManager.get_token(json_param_object, pid)
        project_id = HcsManager.get_params_by_key(json_param_object, "projectId")

        # 备份的url
        ctrl_domain = HcsManager.get_params_by_key(json_param_object, "businessAddr")
        get_log_backup_status_url = f'{ctrl_domain}/gaussdb/v3.1/{project_id}/backups?' \
                                    f'instance_id={instance_id}&backup_type=Snapshot_Xbsa'
        backup_header = {'X-Auth-Token': token, 'X-Language': 'en-us'}
        log.info(f"get_log_backup_job_progress get_log_backup_status_url{get_log_backup_status_url}")
        ret, ret_body, ret_header = request_get(get_log_backup_status_url, backup_body, backup_header)
        clear(token)
        if not ret:
            log.error("Failed get progress!")
            return {}
        if ret_body.get("error_code"):
            log.error(f'Exec GET error with return: {ret_body.get("error_msg")}')
            return {}
        log.info(f"get_log_back_progress: {ret_body}")
        return ret_body

    @staticmethod
    def start_backup(json_param_object, pid, backup_body):
        token = HcsManager.get_token(json_param_object, pid)
        project_id = HcsManager.get_params_by_key(json_param_object, "projectId")
        # 备份的url
        ctrl_domain = HcsManager.get_params_by_key(json_param_object, "businessAddr")
        backup_url = f'{ctrl_domain}/gaussdb/v3/{project_id}/backups'
        backup_header = {'X-Auth-Token': token, 'X-Language': 'en-us'}
        log.info(f"start_backup backup_body{backup_body}")
        ret, ret_body, ret_header = request_post(backup_url, backup_body, backup_header)
        clear(token)
        if not HcsManager.check_ret_body(ret, ret_body):
            return {}
        log.info('Succeed start backup!')
        return ret_body

    @staticmethod
    def start_restore(json_param_object, pid, restore_body):
        token = HcsManager.get_token(json_param_object, pid)
        ctrl_domain = HcsManager.get_params_by_key(json_param_object, "businessAddr")
        project_id = HcsManager.get_params_by_key(json_param_object, "projectId")
        restore_url = f'{ctrl_domain}/gaussdb/v3/{project_id}/instances/recovery'
        restore_header = {'X-Auth-Token': token, 'X-Language': 'en-us'}
        log.info(f"start_restore restore_body{restore_body}")
        ret, ret_body, ret_header = request_post(restore_url, restore_body, restore_header)
        clear(token)
        if not ret:
            log.error("Failed exec restore!")
            return {}
        if ret_body.get("error_code"):
            log.error(f'Exec POST error with return: {ret_body.get("error_msg")}')
            raise Exception(ret_body.get("error_msg", ""))
        log.info('Succeed start restore!')
        return ret_body

    @staticmethod
    def check_ret_body(ret, ret_body):
        if not ret:
            log.error("Failed start backup!")
            return False
        if ret_body.get("error_code"):
            log.error(f'Exec POST error with return: {ret_body.get("error_msg", "")}')
            raise Exception(ret_body.get("error_code"), ret_body.get("error_msg", ""))
        return True

    @staticmethod
    def get_params_by_key(param, json_const):
        result = param.get("job", {}).get("protectObject", {}).get("extendInfo", {}).get(json_const, "")
        if not result:
            copies_info = param.get("job", {}).get("copies", [])
            result = copies_info[len(copies_info) - 1].get("protectObject", {})\
                .get("extendInfo", {}).get(json_const, "")
            if not result:
                log.error(f"Get param protectObject_extendInfo_json_const failed.")
        return result
